﻿using Microsoft.Web.WebView2.Core;

namespace Digitalmes.Gallery.Views.Pages;

public partial class WebViewPage : INavigableView<WebViewViewModel>
{
    public WebViewViewModel ViewModel { get; }

    public WebViewPage(WebViewViewModel viewModel)
    {
        ViewModel = viewModel;
        DataContext = this;

        InitializeComponent();
        InitializeAsync();
    }

    private async void InitializeAsync()
    {
        // 初始化 WebView2
        await webView.EnsureCoreWebView2Async(null);
       
        if (!IsInstallWebview2())
        {
            // 提示 CoreWebView2 没有安装
            System.Windows.MessageBox.Show("本地没有检测到 WebView2 Runtime，请确认是否有安装");
        }

        // 本机和 Web 端代码的互操作，可参考：https://learn.microsoft.com/zh-cn/microsoft-edge/webview2/how-to/communicate-btwn-web-native
        if (webView?.CoreWebView2 != null)
        {
            // JS 页面代码
            // <script>
            //   window.chrome.webview.postMessage("");
            // </script>

            // CS 向 JS 发送数据。
            // webView.CoreWebView2.PostWebMessageAsJson(JsonSerializer.Serialize(...));

            // JS 页面代码
            // <script>
            //   window.chrome.webview.addEventListener('message', arg => {
            //     const data = arg.data;
            //   });
            // </script>

            // 接收 JS 端数据
            webView.CoreWebView2.WebMessageReceived += WebView2WebMessageReceived;

            // 注册 JS 脚本
            await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync("window.chrome.webview.postMessage('setup');");
            await webView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(@"
window.chrome.webview.addEventListener('message', arg => { 
    const data = JSON.parse(arg.data);
    if (data.type === 'setup') {
        window.localStorage.setItem('WebView2', true);
        window.localStorage.setItem('app_client_setup', arg.data);
    } else if (data.type === 'input') {
        window.localStorage.setItem('app_client_input', arg.data);
    }
});"
);

            // 采用 Source 初始化和 Navigate 导航存在区别。
            // 注：导航必须在注册脚本和回调事件之后，否则页面必须再刷新后脚本才生效。
            webView.CoreWebView2.Navigate(ViewModel.ServerUrl);
        }
    }

    private void Polling()
    {
        if (webView?.CoreWebView2 != null)
        {
            _ = Task.Run(async () =>
            {
                await Task.CompletedTask;

                // 从 Channel 中读取数据

                Dictionary<string, object> map = new()
                    {
                        { "type", "input" },
                    };
                // 注：必须要由主线程调用才有效
                _ = Dispatcher.InvokeAsync(() =>
                {
                    map["sn"] = DateTime.Now.AddDays(-1).ToString();
                    webView.CoreWebView2.PostWebMessageAsString(map.ToJson());
                });
            });
        }
    }

    void WebView2WebMessageReceived(object? sender, CoreWebView2WebMessageReceivedEventArgs args)
    {
        var msg = args.TryGetWebMessageAsString();
        if (msg == "setup")
        {
            Dictionary<string, object> map = new()
            {
                { "type", "setup" },
                { "lineCode", ViewModel.LineCode },
                { "opCode", ViewModel.OpCode },
            };
            webView.CoreWebView2.PostWebMessageAsString(map.ToJson());
        }
        else if (msg == "input")
        {
            Dictionary<string, object> map = new()
            {
                { "type", "input" },
            };
            webView.CoreWebView2.PostWebMessageAsString(map.ToJson());
        }
    }

    /// <summary>
    /// 检测是否有安装 Webview2
    /// </summary>
    /// <returns></returns>
    private static bool IsInstallWebview2()
    {
        try
        {
            var version = CoreWebView2Environment.GetAvailableBrowserVersionString(null);
            return !string.IsNullOrEmpty(version);
        }
        catch (Exception)
        {
            return false;
        }
    }
}
